TOOL.Category = "Weapons"
TOOL.Name = "#Gate Overloader"
TOOL.Command = nil
TOOL.ConfigName = ""
TOOL.Tab = "Stargate"
TOOL.AddToMenu = false -- Tell GMod not to add this STool. aVoN's code will do it later.

local entityName = "gate_overloader"

local models = 
{
   "models/pyro_overloader/overloader.mdl",
   "models/portal/turret.mdl",
   "models/overloader/overloader.mdl",
   "models/props/turret_01.mdl"
}

TOOL.ClientConVar['energyOutput'] = "5000"
TOOL.ClientConVar['isBeamCoherent'] = "0"
TOOL.ClientConVar['model'] = models[1]

cleanup.Register(entityName)

if(CLIENT || !SERVER) then
	language.Add("Tool_"..entityName.."_name", 'Gate Overloader')
	language.Add("Tool_"..entityName.."_desc", 'Overloads a remote stargate, given enough energy.')
	language.Add("Tool_"..entityName.."_0", 'Left click: Place weapon.   Right click: Setup weapon.')
	language.Add("Undone_"..entityName, 'Gate overloader undone')
	language.Add("Cleanup_"..entityName, 'Gate Overloaders')
	language.Add("Cleaned_"..entityName, 'Removed all gate overloaders')
	language.Add("SBoxLimit_"..entityName, 'Maximum number of gate overloaders created')
end

if(SERVER || !CLIENT) then 
   CreateConVar("sbox_max"..entityName, 4)
   
   function TOOL:MakeGateOverloader(energyOutput, isBeamCoherent, player, position, upVector, angle, modelPath)
      if(!player:CheckLimit(entityName)) then 
         return nil 
      end
        
      local gateCannon = ents.Create(entityName)
      
      if(gateCannon == nil || gateCannon:IsValid() == false) then
         error("Could not spawn gate overloader.\n")
      end
      
      gateCannon:SetModel(modelPath)
      gateCannon:SetAngles(angle)
      gateCannon:SetPos(position + upVector * gateCannon:BoundingRadius())
      gateCannon:SetVar("Owner", player)
      gateCannon:SetEnergyUsage(energyOutput)
      gateCannon:SetIsBeamCoherent(isBeamCoherent)
      gateCannon:Spawn()
      gateCannon:Activate()
        
      player:AddCount(entityName, gateCannon)
      return gateCannon
   end
end

function TOOL:LeftClick(trace)
   if(trace.Hit == false || (trace.Entity && trace.Entity:IsPlayer())) then 
      return false 
   elseif(CLIENT || !SERVER) then
      return true
   elseif(!self:GetSWEP():CheckLimit(entityName)) then 
      return false 
   end
   
   local player = self:GetOwner()
    
   local angle = trace.HitNormal:Angle()
   angle.pitch = angle.pitch + 90
   angle.yaw = trace.Normal:Angle().yaw
   
   local overloader = self:MakeGateOverloader(self:GetClientNumber("energyOutput"), 
                                              self:GetClientNumber("isBeamCoherent"),
                                              player, 
                                              trace.HitPos,
                                              trace.HitNormal,
                                              angle, 
                                              self:GetClientInfo("model"))
   
   if(overloader == nil || overloader:IsValid() == false) then
      error("Could not create a gate overloader.\n")
   end
   
   if(trace.HitNonWorld) then
      weld = constraint.Weld(overloader, trace.Entity, 0, trace.PhysicsBone, 0, true)
      noCollide = constraint.NoCollide(overloader, trace.Entity, 0, trace.PhysicsBone)
      trace.Entity:DeleteOnRemove(overloader)
   else
      local overloaderPhysics = overloader:GetPhysicsObject()
      
      if(overloaderPhysics:IsValid()) then
         overloaderPhysics:Wake()
         overloaderPhysics:EnableMotion(true)
      end
   end
   
   undo.Create(entityName)
   undo.AddEntity(overloader)
   
   if(trace.Entity:IsValid()) then
      undo.AddEntity(weld)
      undo.AddEntity(noCollide)
   end
   
   undo.SetPlayer(player)
   undo.Finish()
   player:AddCleanup(entityName, overloader)
    
   return true
end

function TOOL:RightClick(trace)
   if(trace.Entity == nil || trace.Entity:GetClass() ~= entityName) then
      return false
   elseif(CLIENT || !SERVER) then
      return true
   end
   
   local overloader = trace.Entity
   
   overloader:SetEnergyUsage(self:GetClientNumber("energyOutput"))
   overloader:SetIsBeamCoherent(self:GetClientNumber("isBeamCoherent"))
   
   return true
end

function TOOL.BuildCPanel(panel)
	panel:AddControl("Header", 
   {
      Text = "#Tool_"..entityName.."_name", 
      Description = "#Tool_"..entityName.."_desc"
   })
   
   panel:AddControl("Slider", 
   {
      Label = "Energy Beam Power:", 
      Type = "Integer", 
      Min = 1000, Max = 10000, 
      Command = entityName.."_energyOutput"
   })
   
   panel:AddControl("CheckBox", 
   {
		Label = "Focus Beam",
		Description = "Make the beam come out of the remote gate.",
		Command = entityName.."_isBeamCoherent"
	})
   
   for _, model in pairs(models) do
      if(file.Exists("../"..model)) then
         list.Set(entityName.."Models", model, {})
      end
   end
   
   panel:AddControl("PropSelect", 
   {
		Label = "Model:",
		ConVar = entityName.."_model",
		Category = "Stargate",
		Models = list.Get(entityName.."Models")
   })
end
